import 'dart:math';

import 'package:flutter/material.dart';

/// create at 2021/7/15
/// by yjl
/// describe：

class CustomPaintPage extends StatefulWidget {
  CustomPaintPage({Key? key}) : super(key: key);

  @override
  _CustomPaintPageState createState() => _CustomPaintPageState();
}

class _CustomPaintPageState extends State<CustomPaintPage>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;

  List<Snowflake> _datas = List.generate(100, (index) {
    return Snowflake();
  });

  @override
  void initState() {
    _animationController =
        AnimationController(vsync: this, duration: Duration(seconds: 1))
          ..repeat();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("CustomPaintPage"),
      ),
      body: Center(
        child: Container(
          constraints: BoxConstraints.expand(),
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  colors: [Colors.blue, Colors.lightBlue, Colors.white],
                  stops: [0.0, 0.7, 0.95])),
          child: AnimatedBuilder(
            builder: (BuildContext context, Widget? child) {
              _datas.forEach((element) {
                element.fall();
              });
              return CustomPaint(
                painter: MyCustomPainter(_datas),
              );
            },
            animation: _animationController,
          ),
        ),
      ),
    );
  }
}

class MyCustomPainter extends CustomPainter {
  final List<Snowflake> _datas;
  final whitePaint = Paint()..color = Colors.white;

  MyCustomPainter(this._datas);

  @override
  void paint(Canvas canvas, Size size) {
    //loge(size);
    //canvas.drawCircle(Offset(size.width/2, size.height/2), 20, Paint());
    canvas.drawCircle(size.center(Offset(0, 100)), 60, whitePaint);
    canvas.drawOval(
        Rect.fromCenter(
            center: size.center(Offset(0, 280)), width: 200, height: 250),
        whitePaint);

    _datas.forEach((snowflake) {
      canvas.drawCircle(
          Offset(snowflake.x, snowflake.y), snowflake.radius, whitePaint);
    });
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

class Snowflake {
  double x = Random().nextDouble() * 400;
  double y = Random().nextDouble() * 800;
  double radius = Random().nextDouble() * 2 + 2;
  double velocity = Random().nextDouble() * 4 + 2;

  fall() {
    y += velocity;
    if (y > 800) {
      y = 0;
      x = Random().nextDouble() * 400;
      radius = Random().nextDouble() * 2 + 2;
      velocity = Random().nextDouble() * 4 + 2;
    }
  }
}
